package com.heima.search.service.Impl;

import com.alibaba.fastjson.JSON;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.common.search.pojo.ApUserSearch;
import com.heima.model.common.search.pojo.ArticleDoc;
import com.heima.model.common.search.dto.SearchDto;
import com.heima.search.service.HistoryService;
import com.heima.search.service.SerchService;
import com.heima.utils.common.UserContext;
import org.apache.commons.lang.StringUtils;
import org.checkerframework.checker.units.qual.A;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class SerchServiceImpl implements SerchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;
    @Autowired
    private HistoryService historyService;
    /**
     * 搜索功能
     * @param dto
     * @return
     */
    @Override
    public ResponseResult<List<ArticleDoc>> search(SearchDto dto) throws IOException {
        String searchWords = dto.getSearchWords();
        if (StringUtils.isBlank(searchWords)){
             return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        //如果是游客不保存搜索历史
        Long userId = UserContext.getUserId();
        if (userId!=null){
            ApUserSearch apUserSearch = new ApUserSearch();
            apUserSearch.setUserId(userId);
            apUserSearch.setKeyword(searchWords);
            apUserSearch.setCreatedTime(new Date());
            historyService.saveSearchHistory(apUserSearch);
        }

        SearchRequest seachRequest= new SearchRequest("app_info_article");

        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();
        queryBuilder.must(QueryBuilders.multiMatchQuery(searchWords,"title","content"));
        if (dto.getMinBehotTime().before(new Date())&&dto.getMinBehotTime()!=null){
            //前端传递MinBehotTime大于当前时间2603-01-01
            queryBuilder.must(QueryBuilders.rangeQuery("publishTime").lt(dto.getMinBehotTime()));
        }
        seachRequest.source().query(queryBuilder);
        seachRequest.source().sort("publishTime", SortOrder.DESC);
        seachRequest.source().from(0);
        seachRequest.source().size(5);
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("title");
        highlightBuilder.preTags("<font style='color: red; font-size: inherit;'>");
        highlightBuilder.postTags("</font>");
        seachRequest.source().highlighter(highlightBuilder);
        SearchResponse searchResponse = restHighLevelClient.search(seachRequest, RequestOptions.DEFAULT);
        SearchHits hits = searchResponse.getHits();
        SearchHit[] hitsHits = hits.getHits();
        List<ArticleDoc> list = new ArrayList<>();
        for (SearchHit hitsHit : hitsHits) {
            String json = hitsHit.getSourceAsString();
            ArticleDoc articleDoc = JSON.parseObject(json, ArticleDoc.class);
            //获取带高亮的标题，将source中不带高亮标题替换掉。
            Map<String, HighlightField> highlightFields = hitsHit.getHighlightFields();
            if (highlightFields!=null){
                HighlightField highlightField = highlightFields.get("title");
                if (highlightField!=null){
                    Text[] fragments = highlightField.fragments();
                    Text text = fragments[0];
                    articleDoc.setTitle(text.toString());
                }
            }
              list.add(articleDoc);
        }

        return ResponseResult.okResult(list);
    }
}
